package com.bosssoft.boss_exam_core.common.Filter;



import com.bosssoft.boss_exam_core.common.config.security.AdminJwtTokenHelper;
import com.bosssoft.boss_exam_core.util.web.ResponseUtil;
import com.bosssoft.boss_exam_db.entity.Admin;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.JwtException;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;

/**
 * jwt token验证类,验证成功后设置进去SecurityContext中
 */
public class VerifyTokenFilter extends OncePerRequestFilter {

    private AdminJwtTokenHelper jwtTokenUtil;

    public VerifyTokenFilter(AdminJwtTokenHelper jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            String requestURI = request.getRequestURI();
            String contextPath = request.getContextPath();
            //todo 静态资源也该放行//如果是文档查看，放行
            AntPathMatcher antPathMatcher = new AntPathMatcher();
            //todo 如果是访问swagger无需鉴权
            if(
                    antPathMatcher.match("/swagger-ui.html",requestURI)
                    ||antPathMatcher.match("/swagger-resources/**",requestURI)
                    ||antPathMatcher.match("/images/*",requestURI)
                    ||antPathMatcher.match("/webjars/**",requestURI)
                    ||antPathMatcher.match("/v2/api-docs",requestURI)
                    ||antPathMatcher.match("/configuration/ui",requestURI)
                    ||antPathMatcher.match("/configuration/security",requestURI)){
                filterChain.doFilter(request, response);
//                如果是登入无需鉴权
            } else if ((contextPath+"/admin/auth/login").equals(requestURI)) {
                filterChain.doFilter(request, response);
//                如果是请求公钥，无需鉴权
            }else if((contextPath+"/admin/security/publicKey").equals(requestURI)){
                filterChain.doFilter(request, response);
            }else {
                Optional<Admin> admin = jwtTokenUtil.verifyToken(request);
                System.err.println("VerifyTokenFilter result: {}" + admin.orElse(null));
                filterChain.doFilter(request, response);
            }
        } catch (JwtException e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            //可以在这里指定重定向还是返回错误接口示例
            Object respBean = ResponseUtil.CheckTokenFail();
            ObjectMapper om = new ObjectMapper();
            PrintWriter out = response.getWriter();
            out.write(om.writeValueAsString(respBean));
            out.flush();
            out.close();
        }
    }
}
